package pers.mor.tomcat.catalina;

import cn.hutool.log.LogFactory;
import pers.mor.tomcat.http.CompressionConfig;
import pers.mor.tomcat.http.HttpProcessor;
import pers.mor.tomcat.http.Request;
import pers.mor.tomcat.http.Response;
import pers.mor.tomcat.util.ThreadUtil;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Connector implements Runnable {

    private int port;
    private String protocol;

    private CompressionConfig compression;

    public Connector(int port, String protocol) {
        this.port = port;
        this.protocol = protocol;
        this.compression = new CompressionConfig();
    }

    public void init() {
        LogFactory.get().info("Initializing ProtocolHandler [http-bio-{}]",port);
    }

    public void start() {
        LogFactory.get().info("Starting ProtocolHandler [http-bio-{}]", this.port);
        new Thread(this).start();
    }

    @Override
    public void run() {
        // 当浏览器访问服务器时，其实是和服务器建立了通讯连接。
        // 当服务器响应时，其实就是给浏览器发送了一些数据。
        try {
            // ServerSocket中源码if (port < 0 || port > 0xFFFF)
            // 规范了端口号必须大于0并且小于65535
            ServerSocket serverSocket = new ServerSocket(this.port);
            while (true) {
                Socket socket = serverSocket.accept();
                Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Request request = new Request(socket);
                            Response response = new Response();

                            synchronized (compression) {
                                compression.checkIfBrowserIsSupportive(request);
                                response.acceptCompression(compression);
                            }

                            HttpProcessor processor = new HttpProcessor();
                            processor.execute(socket, request, response);

                        } catch (IOException e) {
                            LogFactory.get().error(e);
                        }
                    }
                };

                ThreadUtil.run(task);
            }
        } catch (IOException e) {
            LogFactory.get().error(e);
        }
    }

    public int getPort() {
        return this.port;
    }

    public String getProtocol() {
        return this.protocol;
    }

    public CompressionConfig compression() {
        return this.compression;
    }

}
